#ifndef __WIZ_ARCHIVE_SERIALIZER_UTILS_NVP_HPP__SHANHAOBO_19800429__
#define __WIZ_ARCHIVE_SERIALIZER_UTILS_NVP_HPP__SHANHAOBO_19800429__

#include "./WizArchiveForwardDeclare.hpp"
#include "./WizArchiveSerializerUtilsSplit.hpp"
#include "./WizArchiveSerializerUtilsBaseClass.hpp"

namespace Wiz
{
    namespace Archive
    {
        namespace Serializer
        {
            namespace Utils
            {
                /// Name-Value-Pair
                namespace NVP
                {
                    template<class T>
                    struct Type : public ::std::pair<const char *, T *>
                    {
                        typedef ::std::pair<const char *, T *> tSuper;

                        explicit Type(const char * name_, T & t) : tSuper(name_, (T*)(& t))
                        {}

                        Type(const Type & rhs) : tSuper(rhs.first, (T*)rhs.second)
                        {}

                        const char * Name() const
                        {
                            return this->first;
                        }
                        T & Value() const
                        {
                            return *(this->second);
                        }

                        const T & ConstValue() const
                        {
                            return *(this->second);
                        }

                        template<class ArchiveT, class DataT>
                        static ::Wiz::Void::Type Write(
                            ArchiveT &          InArchive, 
                            DataT &             InData, 
                            ::Wiz::UInt32::In   InVer
                            )
                        {
                            InArchive.operator<<(ConstValue());
                        }

                        template<class Archive, class T>
                        static ::Wiz::Void::Type Read(
                            ArchiveT &          InArchive, 
                            DataT &             InData, 
                            ::Wiz::UInt32::In   InVer
                            )
                        {
                            InArchive.operator>>(Value());
                        }

                        WIZ_ARCHIVE_SERIALIZER_UTILS_SPLIT_INTRUSIVE()
                    };
                } /// end of namespace NVP
            } /// end of namespace Utils

            template<class DataT>
            WIZ_INLINE const ::Wiz::Archive::Serializer::Utils::NVP::Type< DataT >
                MakeNVP(const char * InNamePtr, T & InData)
            {
                return ::Wiz::Archive::Serializer::Utils::NVP::Type< DataT >(InNamePtr, InData);
            }
        } /// end of namespace Serializer
    } /// end of namespace Archive
} /// end of namespace Wiz

#define WIZ_ARCHIVE_SERIALIZER_UTILS_NVP(Name)                              \
    ::Wiz::Archive::Serializer::MakeNVP(WIZ_MPP_STRINGIZE(Name), Name);


#define WIZ_ARCHIVE_SERIALIZER_UTILS_NVP_BASECLASS(Name)                    \
    ::Wiz::Archive::Serializer::MakeNVP(                                    \
        WIZ_MPP_STRINGIZE(Name),                                            \
        ::Wiz::Archive::Serializer::Utils::BaseClass::Acquire<Name>(*this)  \
    )

#endif /*__WIZ_ARCHIVE_SERIALIZER_UTILS_BASECLASS_HPP__SHANHAOBO_19800429__*/
